package cn.lyvust.first.api;

import cn.lyvust.first.common.bean.ResponseCode;
import cn.lyvust.first.common.bean.ResponseResult;
import cn.lyvust.first.common.util.ImageUtils;
import cn.lyvust.first.common.util.PathUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ggzheng
 * @date 2021-01-21
 */
@Api(tags = {"文件上传"})
@RestController
@RequestMapping("/common/file")
public class FileUpload {
    private Logger log = LoggerFactory.getLogger(this.getClass());

    private static final String SLASH = "/";
    private static final String PERIOD = ".";

    @Value("${oss.thumb_format}")
    private String thumb_format;

    @Value("${oss.project_name}")
    private String project_name;

    @Value("${oss.res_path}")
    private String res_path;

    //文件准许上传格式导入
    @Value("${oss.image}")
    private String image;
    @Value("${oss.video}")
    private String video;
    @Value("${oss.doc}")
    private String doc;
    @Value("${oss.file}")
    private String file;

    //文件存储路径导入
    @Value("${oss.upload_image_path}")
    private String upload_image_path;
    @Value("${oss.upload_thumb_path}")
    private String upload_thumb_path;
    @Value("${oss.upload_video_path}")
    private String upload_video_path;
    @Value("${oss.upload_file_path}")
    private String upload_file_path;
    @Value("${oss.upload_doc_path}")
    private String upload_doc_path;

    @Value("${oss.icon_path}")
    private String icon_path;

    /**
     * @param multipartFile 待上传文件
     * @param moduleName    所属模块，举例：station、core、common
     * @return
     * @throws IOException
     */
    @ApiOperation(value = "文件上传")
    @PostMapping(value = {"/upload"}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseResult upload(@RequestParam("file") MultipartFile multipartFile, String moduleName) {
        log.info("begin upload");
        try {
            //如果文件不为空，写入上传路径
            if (!multipartFile.isEmpty()) {

                //上传文件所在的绝对路径
                String absolutePath = multipartFile.getOriginalFilename();
                log.info("absolutePath = {}", absolutePath);
                //路径处理工具
                PathUtils pathUtils = new PathUtils(absolutePath, moduleName, project_name);

                //filename:文件名
                String filename = pathUtils.filename();
                //extension:扩展名
                String extension = pathUtils.extension();

                //relativePath:相对路径 /projectName/module/yyyy/MMdd/uuid.ext
                String relativePath = pathUtils.relativePath();

                String fileType = "此格式的文件不允许上传!";

                //根据扩展名判断文件类型
                boolean isImage = image.indexOf(extension) != -1;
                boolean isVideo = video.indexOf(extension) != -1;
                boolean isDoc = doc.indexOf(extension) != -1;
                boolean isFile = file.indexOf(extension) != -1;

                log.info("relativePath = {}", relativePath);

                //存储路径
                String savePath = null;
                if (isImage) {
                    savePath = upload_image_path;
                    fileType = "图片";
                } else if (isVideo) {
                    savePath = upload_video_path;
                    fileType = "视频";
                } else if (isDoc) {
                    savePath = upload_doc_path;
                    fileType = "文档";
                } else if (isFile) {
                    savePath = upload_file_path;
                    fileType = "文件";
                } else {
                    return ResponseResult.e(ResponseCode.FAIL, fileType);
                }

                // fileType + /projectName/module/yyyy/MMdd/uuid.ext
                String resourcePath = savePath.substring(savePath.lastIndexOf(SLASH)) + relativePath;

                // D:/root/fileType + /projectName/module/yyyy/MMdd/uuid.ext
                savePath += relativePath;

                log.info("savePath = {}", savePath);

                File newFile = new File(savePath);
                //判断路径是否存在，如果不存在就创建一个
                if (!newFile.getParentFile().exists()) {
                    boolean fileFlag = newFile.getParentFile().mkdirs();
                    log.info("fileFlag = {}", fileFlag);
                }
                log.info("newFile = {}", newFile);
                multipartFile.transferTo(newFile);

                Map<String, String> result = new HashMap<>();
                result.put("fileName", filename);//文件上传时的名字，最初的名字
                result.put("extName", extension);//扩展名
                result.put("fileSize", String.valueOf(multipartFile.getSize()));//文件大小
                result.put("fileType", fileType);//文件类型

                result.put("resPath", res_path);
                result.put("uploadFile", resourcePath);

                //如果是图片，执行图片压缩
                if (isImage) {
                    //savePath:     D:/root/thumb + /projectName/module/yyyy/MMdd/uuid.ext
                    //outPutPath:   D:/root/thumb + /projectName/module/yyyy/MMdd/uuid
                    ImageUtils.imageCompression(savePath, upload_thumb_path + pathUtils.relativePathNotExtension(), thumb_format); //调用图片压缩方法，生成缩略图

                    //http://localhost:7777 + /thumb + /projectName/module/yyyy/MMdd/uuid + . + jpg
                    result.put("thumbFile", res_path + upload_thumb_path.substring(upload_thumb_path.lastIndexOf(SLASH)) + pathUtils.relativePathNotExtension() + PERIOD + thumb_format);
                } else {
                    //http://localhost:7777 + /icon + / + ext + . + 'ico'
                    result.put("thumbFile", res_path + icon_path.substring(icon_path.lastIndexOf(SLASH)) + SLASH + extension + PERIOD + "ico");
                }
                log.info("result = {}", result);

                return ResponseResult.e(ResponseCode.OK, result);
            } else {
                return ResponseResult.e(ResponseCode.FILE_EMPTY);
            }
        } catch (Exception e) {
            log.info(e.getMessage());
        }
        return ResponseResult.e(ResponseCode.FILE_EMPTY);
    }
}
